# -*- coding: utf-8 -*-
"""
# 使用了 [openpyxl==3.1.2]，遵循其 [MIT] 许可证，原始代码来源：[https://openpyxl.readthedocs.io]
# 使用了 [pandas==2.0.3]，遵循其 [BSD 3-Clause License] 许可证，原始代码来源：[https://pandas.pydata.org]
# 使用了 [tqdm==4.67.1]，遵循其 [MIT] 许可证，原始代码来源：[https://tqdm.github.io]
"""
import os
import re
import pandas as pd
import sys
import glob
import datetime
from multiprocessing import Pool
from tqdm import tqdm
from openpyxl import Workbook
from openpyxl.styles import Alignment, Font, Border, Side
from openpyxl.utils import get_column_letter
from pathlib import Path
from openpyxl import load_workbook
from openpyxl.cell.rich_text import TextBlock,CellRichText
from openpyxl.cell.text import InlineFont

RESULT_DIR=Path("./result")
PAT_CLEAN=re.compile(r'[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F]')
#KEY_PTN=r"工具理性|技术理性|效率理性|功效理性"
#KEY_PTN=r"价值理性|实质理性"
#KEY_PTN=r"(政府即平台).*?(英国|美国|法国|德国|意大利|西班牙|新加坡)|(英国|美国|法国|德国|意大利|西班牙|新加坡).*?(政府即平台)"
KEY_PTN=r"金xx"
PAT_KEYWORDS=re.compile(f"(.{{0,10}})({KEY_PTN})(.{{0,50}})")
THIN_BORDER = Border(
    left=Side(style='thin'), right=Side(style='thin'),
    top=Side(style='thin'), bottom=Side(style='thin')
)
BASE_FONT=Font(name="SimSun",size=9)
RED=InlineFont(color="FF0000",rFont="SimSun",sz=9)
BLACK=InlineFont(color="000000",rFont="SimSun",sz=9)

def split_by_matches(string, pattern):
    matches = list(re.finditer(pattern, string))
    if not matches:
        return [string]
    segments = []
    start_index = 0
    for match in matches:
        if match.start() > start_index:
            segments.append(string[start_index:match.start()])
        segments.append(match.group())
        start_index = match.end()
    if start_index < len(string):
        segments.append(string[start_index:])
    return segments

def save_dataframe(df,prefix=""):
    RESULT_DIR.mkdir(parents=True, exist_ok=True)

    ticks = pd.Timestamp.now().strftime('%Y%m%d_%H%M%S')
    fn=f"./{prefix}_{re.split(r'[_.]',os.path.basename(sys.argv[0]))[0]}_{ticks}.xlsx" if prefix else f"./{re.split(r'[_.]',os.path.basename(sys.argv[0]))[0]}_{ticks}.xlsx"
    fp=RESULT_DIR/fn

    with pd.ExcelWriter(fp, engine='openpyxl') as writer:
        df.to_excel(writer,index=False)
        workbook=writer.book
        worksheet=writer.sheets['Sheet1']
        worksheet.freeze_panes = 'A2'
        max_col = worksheet.max_column
        for col in range(1,max_col+1):#handler first row.
            cell=worksheet.cell(1,col)
            if cell.value:
                cell.font=Font(name="SimSun",bold=True,color="000000",size=9)
                cell.alignment=Alignment(horizontal="center",vertical='center')
        for row in worksheet.iter_rows(min_row=2,max_row=worksheet.max_row):#handler other rows.
            for cell in row:
                cell.alignment=Alignment(horizontal='left' if cell.column==3 else 'center',vertical='center',wrapText=True)
                cell.font=BASE_FONT
                cell.border=THIN_BORDER
        for row_idx in range(1,worksheet.max_row+1):#set row height.
            worksheet.row_dimensions[row_idx].height=12
        max_len=0
        for cell in worksheet["D"]:
            if cell.value:
                lines=str(cell.value).splitlines()
                cell_max_len=max(len(line) for line in lines) if lines else 0
                max_len=max(max_len,cell_max_len)
                li_split=split_by_matches(cell.value,KEY_PTN)
                red_string=CellRichText([TextBlock(RED,i) if re.match(KEY_PTN,i) else TextBlock(BLACK,i) for i in li_split])
                cell.value=red_string
        adjusted_width=min((max_len+2)*1.6,160)
        worksheet.column_dimensions["D"].width=adjusted_width
    return fp

def process_md(file_path):
    try:
        modification_time=os.path.getmtime(file_path)
        dt_obj=datetime.datetime.fromtimestamp(modification_time)
        readable_date=dt_obj.strftime('%Y-%m-%d %H:%M:%S')
        with open(file_path,'r',encoding='utf-8',errors='ignore') as f:
            text=PAT_CLEAN.sub("",f.read())
            if matches:=PAT_KEYWORDS.findall(text):
                context=["".join(m) for m in matches]
                link=r"=HYPERLINK("+"\""+os.path.join(os.path.dirname(file_path),os.path.basename(file_path))+"\""+",\""+os.path.basename(file_path)+"\")"
#                print(link)
                return {
                    "文件路径":os.path.dirname(file_path),
                    "修改时间":readable_date,
                    "文件名":link,
                    "匹配内容":"\n".join(context),
                    "频次":len(matches)
                }
    except Exception as e:
        print(f"处理失败 {file_path}: {str(e)}")
    return None

def scan_mds(target_dir,max_workers=os.cpu_count()*2):
    file_list=list(Path(target_dir).rglob("*.md"))
    with Pool(max_workers) as pool:
        results = list(tqdm(pool.imap(process_md,file_list),total=len(file_list),ncols=60,mininterval=0.2,desc="处理进度"))
    if valid_data := [r for r in results if r]:
        fp=save_dataframe(pd.DataFrame(valid_data))

if __name__ == "__main__":
    scan_mds(r"/media/sq/F:/A_PPC/2025/05_xx办公室")
